/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yonsei.iwb.sdt.refinement.generator;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;
import java.util.List;
import java.util.Vector;
import org.yonsei.iwb.sdt.algorithm.DCSSearcher;
import org.yonsei.iwb.sdt.datastructure.tree.BranchingType;
import org.yonsei.iwb.sdt.datastructure.DecomposeCandidate;
import org.yonsei.iwb.sdt.datastructure.DecomposeCandidateSet;
import org.yonsei.iwb.sdt.ontology.PropertyArc;
import org.yonsei.iwb.sdt.refinement.DLConstructors;
import org.yonsei.iwb.sdt.refinement.ExpandingHistory;
import org.yonsei.iwb.sdt.refinement.ExpandingHistorySet;
import org.yonsei.iwb.sdt.refinement.QualificationRefinement;
import org.yonsei.iwb.sdt.refinement.Refinement;
import org.yonsei.iwb.sdt.refinement.RefinementType;
import org.yonsei.iwb.sdt.util.SDTLog;
import org.yonsei.iwb.sdt.util.UtilFunctions;

/**
 *
 * @author JDK
 */
public class QualificationRefinementMaker extends Thread {

    private Model model;
    private Vector<Resource> instanceSet;
    private PropertyArc pa;
    private Resource conclass;
    private Vector<PropertyArc> hisPAset;
    private DecomposeCandidateSet dcs;
    private QuantificationRefinementMaker qrm;

    public QualificationRefinementMaker(Model model, Vector<Resource> instanceSet) {
        this.model = model;
        this.instanceSet = instanceSet;
        this.qrm = new QuantificationRefinementMaker(this.model, RefinementType.QUALIFICATION);
    }

    public QualificationRefinementMaker(Model model, PropertyArc pa, Resource conclass, Vector<PropertyArc> hisPAset, Vector<Resource> instanceSet, DecomposeCandidateSet dcs) {
        this.hisPAset = hisPAset;
        this.pa = pa;
        this.conclass = conclass;
        this.dcs = dcs;
        this.model = model;
        this.instanceSet = instanceSet;
        this.qrm = new QuantificationRefinementMaker(this.model, RefinementType.QUALIFICATION);
    }

    @Override
    public synchronized void run() {
        long startTime = System.currentTimeMillis();
        boolean gen = decomposeCandidateOfQR();
        DCSSearcher.FLAGNUM--;
        long endTime = System.currentTimeMillis();
        if (gen) {
            SDTLog.log(SDTLog.DETAIL, "# QR : Property : " + pa.toString() + " / " + this.conclass.getLocalName() + " is generated..." + ((endTime - startTime) / 1000.0f) + "s)\n");
        } else {
            SDTLog.log(SDTLog.DETAIL, "# - QR : Property : " + pa.toString() + " / " + this.conclass.getLocalName() + " is NOT generated..." + ((endTime - startTime) / 1000.0f) + "s)\n");
        }

    }

    private boolean decomposeCandidateOfQR() {
        DecomposeCandidateSet tempdcs = refinementGenerator(pa, conclass, hisPAset);
        if (tempdcs != null) {
            dcs.addAll(tempdcs);
            return true;
        } else {
            return false;
        }
    }

    public DecomposeCandidateSet refinementGenerator(PropertyArc pa, Resource subclass, Vector<PropertyArc> propertySet) {
//        System.out.println("Subclass = " + subclass);
        ResIterator res = this.model.listResourcesWithProperty(RDF.type, subclass);
        List<Resource> css = res.toList();
        Vector<PropertyArc> propertyHistory = new Vector(propertySet);
        propertyHistory.add(pa);
//        System.out.println(" --  " + css.size());

        ExpandingHistorySet ehs = this.qrm.expandingHistoryCounter(propertyHistory, css);
        DecomposeCandidateSet dcs = new DecomposeCandidateSet();

        for (int i = 0; i < ehs.size(); i++) {
            ExpandingHistory eh = ehs.get(i);
            Vector<Refinement> rset = new Vector<Refinement>();
            Refinement pref = new QualificationRefinement("", eh, subclass);
            Refinement nref = new QualificationRefinement(DLConstructors.NEGATION, eh, subclass);
            nref.setBranchingType(BranchingType.NEGATION_TYPE);

            Vector<Resource> is = eh.getInstanceSet();

//            UtilFunctions.printVectorOfResource(is);

            Vector<Resource> cloneSet = new Vector(this.instanceSet);

            for (int j = 0; j < is.size(); j++) {
                Resource result = is.get(j);
                if (this.instanceSet.contains(result)) {
                    pref.setInstanceSet(result);
                    cloneSet.remove(result);
                }
            }
//            UtilFunctions.printVectorOfResource(cloneSet);
            if (!cloneSet.isEmpty() && !pref.getInstanceSet().isEmpty()) {
                nref.setInstanceSet(cloneSet);
                rset.add(pref);
                rset.add(nref);
            } else {
                continue;
            }

            DecomposeCandidate dc = new DecomposeCandidate(rset, pa, RefinementType.QUALIFICATION);
            dcs.add(dc);
        }



        return dcs;
    }

    public DecomposeCandidateSet refinementGenerator2(PropertyArc pa, Resource subclass, Vector<PropertyArc> propertySet) {
//        System.out.println("Subclass = " + subclass);
        ResIterator res = this.model.listResourcesWithProperty(RDF.type, subclass);
        List<Resource> css = res.toList();
        Vector<PropertyArc> propertyHistory = new Vector(propertySet);
        propertyHistory.add(pa);
//        System.out.println(" --  " + css.size());

        ExpandingHistorySet ehs = this.qrm.expandingHistoryCounter(propertyHistory, css);
        DecomposeCandidateSet dcs = new DecomposeCandidateSet();

        for (int i = 0; i < ehs.size(); i++) {
            ExpandingHistory eh = ehs.get(i);
            Vector<Refinement> rset = new Vector<Refinement>();
            Refinement pref = new QualificationRefinement("", eh, subclass);
            Refinement nref = new QualificationRefinement(DLConstructors.NEGATION, eh, subclass);
            nref.setBranchingType(BranchingType.NEGATION_TYPE);

            Vector<Resource> is = eh.getInstanceSet();

//            UtilFunctions.printVectorOfResource(is);

            Vector<Resource> cloneSet = new Vector(this.instanceSet);

            for (int j = 0; j < is.size(); j++) {
                Resource result = is.get(j);
                if (this.instanceSet.contains(result)) {
                    pref.setInstanceSet(result);
                    cloneSet.remove(result);
                }
            }
//            UtilFunctions.printVectorOfResource(cloneSet);
            if (!cloneSet.isEmpty() && !pref.getInstanceSet().isEmpty()) {
                nref.setInstanceSet(cloneSet);
                rset.add(pref);
                rset.add(nref);
            } else {
                continue;
            }

            DecomposeCandidate dc = new DecomposeCandidate(rset, pa, RefinementType.QUALIFICATION);
            dcs.add(dc);
        }



        return dcs;
    }

    private Vector<Resource> getSatisfiedInstanceSet(PropertyArc pa, Resource r) {
        return null;
    }
}
